
/////////////////////// 演示阻塞等待和非阻塞轮询等待完整代码

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <errno.h>
#include <string.h>


//////// 阻塞等待  -  父进程啥也不干

//int main()
//{
//	
//	printf("我是父进程 , 我的 pid  : %d , ppid : %d\n",getpid(),getppid());
//
//	//创建子进程
//	pid_t id = fork();	
//	if(id == 0)
//	{	
//		// 子进程走 5 s
//		int cns = 5;
//		while(cns)
//		{
//			printf("我是子进程 , 我的 pid  : %d , ppid : %d\n",getpid(),getppid());
//			sleep(1);
//			cns--;
//		}
//		// 子进程正常退出
//		exit(0);
//	}
//	
//	sleep(5);
//			
//	int wstatus = 0;
//	//父进程等待 
//	pid_t rid = waitpid(id , &wstatus , 0);
//
//	if(rid > 0)
//	{
//		printf("Wait Success ! , exit code : %d , rid : %d\n", WEXITSTATUS(wstatus) ,rid);
//	}
//
//	else
//	{	
//		printf("Wait Failed ! , err coed : %d -> %s , rid : %d\n",errno,strerror(errno),rid);
//	}
//
//	sleep(10);	
//
//	return 0;
//}
//





/////////////////  非阻塞轮询 -   WNOHANG


///////// 非阻塞 , 父进程在等待过程中可以看自己的事 


// 函数指针类型
typedef void (*func_t)();

// 任务表数组
#define NUM 5
func_t handlers[NUM+1];

// 如下是任务
void DownLoad()
{
    printf("我是一个下载的任务...\n");
}
void Flush()
{
    printf("我是一个刷新的任务...\n");
}
void Log()
{
    printf("我是一个记录日志的任务...\n");
}


// 注册每个任务       任务表    注册的任务函数
void registerHandler(func_t h[], func_t f)
{
    int i = 0;
    for(; i < NUM; i++)
    {
        if(h[i] == NULL) break;
    }
    if(i == NUM)  return;
    h[i] = f;
    h[i+1] = NULL;
}


int main()
{
	
	// 开始注册任务
	registerHandler(handlers, DownLoad);
	registerHandler(handlers, Flush);
	registerHandler(handlers, Log);


	//创建子进程
	pid_t id = fork();	
	if(id == 0)
	{	
		// 子进程走 5 s
		int cns = 5;
		while(cns)
		{
			printf("我是子进程 , 我的 pid  : %d , ppid : %d\n",getpid(),getppid());
			sleep(1);
			cns--;
		}
		// 子进程正常退出
		exit(0);
	}
	
	while(1)
	{			
		int wstatus = 0;
		//父进程等待 , 非阻塞
		pid_t rid = waitpid(id , &wstatus ,  WNOHANG);
			
		// 走这个证明等到了 !!!
		if(rid > 0)
		{
			printf("Wait Success ! , exit code : %d , rid : %d\n", WEXITSTATUS(wstatus) ,rid);
			break; // 等待结束 , 跳出
		}
		// 等待的进程状态没有改变 , 但存在该进程 
		else if(rid == 0 )
		{
		  	 // 这里面做自己的事情
			 // 函数指针进行回调处理 , 开始做注册表中的每个任务 !!!!!
           		 int i = 0;
           		 for(; handlers[i]; i++)
           		 {
			     // 函数回调
           		     handlers[i]();
           		 }
           		 printf("本轮调用结束，子进程没有退出\n");
           		 sleep(1);	
		
		}
		// 等待失败 		
		else 
		{	
			printf("Wait Failed ! , err coed : %d -> %s , rid : %d\n",errno,strerror(errno),rid);
			break; // 等待失败 , 跳出 !
		}

	}

	return 0;
}
